package com.redwine.app.net;


import android.os.Build;
import android.text.TextUtils;
import android.util.Log;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.redwine.app.APP;
import com.redwine.app.net.responses.BaseResponse;
import com.redwine.app.utils.Constants;
import com.redwine.app.utils.ErrorResponseException;
import com.redwine.app.utils.Global;
import com.redwine.app.utils.LogUtil;
import com.redwine.app.utils.NetUtil;
import com.redwine.app.utils.SHA1;

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by tian on 15/4/18:下午3:00.
 * qcl这是自定义GsonRequest类
 */
public class GsonRequest<T> extends Request<T> {

    private final Gson gson = new Gson();

    private final Class<T> clazz;

    private final Response.Listener<T> listener;

    private boolean needsAuthenticate;

    private Map<String, String> params = null;

    public GsonRequest(String url, int method, Class<T> clazz, boolean needsAuthenticate,
                       Map<String, String> params2, Response.Listener<T> listener,
                       Response.ErrorListener errorListener) {
        super(method, url, errorListener);
        this.clazz = clazz;
        this.needsAuthenticate = needsAuthenticate;
        this.listener = listener;
        this.params = getCommonMap();

        if (params2 != null) {
            this.params.putAll(params2);
        }
        LogUtil.e("params", "url" + url);
        LogUtil.e("params", "params" + this.params.toString());
    }

    @Override
    public String getCacheKey() {
        String act = params.get("act");
        return super.getCacheKey() + (TextUtils.isEmpty(act) ? "" : act);
    }


    /*
    * 这里获取请求数据，有些机型可能为空请求不到数据
    * 通过
    * */
    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        long t = (int) (System.currentTimeMillis() / 1000);
        String time = Long.toString(t);//时间戳（单位秒）
        String nonce = "secretMirror_az_app";//任意字段
        String privateKey = "secretMirror_api";
        String temp = time + privateKey + nonce;
        String signature = SHA1.getSha1(temp);//sh1加密后的签名
        //        String token= Settings.getToken();//token
        Map<String, String> params = new LinkedHashMap<>();
        params.put("TIMESTAMP", time);
        params.put("NONCE", nonce);
        params.put("SIGNATURE", signature);
        params.put("os", "Android" + Build.VERSION.RELEASE);
        params.put("appVersion", Constants.version_name);
        params.put("platform", "Android");
        params.put("phoneModel", Build.MODEL);

        //        WifiManager wm = (WifiManager) APP.getInstance().getSystemService(Context.WIFI_SERVICE);
        //        String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
        //        params.put("udid", m_szWLANMAC);
        //        final TelephonyManager tm = (TelephonyManager) APP.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
        //        final String tmDevice = "" + tm.getDeviceId();
        //        params.put("udid", tmDevice);

         /*
        * 不愿加入READ_PHONE_STATE许可。而你仍然想获得唯一序列号之类的东西。这时你可以通过取出ROM版本、制造商、CPU型号、
        * 以及其他硬件信息来实现这一点。这样计算出来的ID不是唯一的（因为如果两个手机应用了同样的硬件以及Rom 镜像）。
        * 但应当明白的是，出现类似情况的可能性基本可以忽略。要实现这一点，你可以使用Build类:*/
        String m_szDevIDShort = "35" +
                Build.BOARD.length() % 10 +
                Build.BRAND.length() % 10 +
                Build.CPU_ABI.length() % 10 +
                Build.DEVICE.length() % 10 +
                Build.DISPLAY.length() % 10 +
                Build.HOST.length() % 10 +
                Build.ID.length() % 10 +
                Build.MANUFACTURER.length() % 10 +
                Build.MODEL.length() % 10 +
                Build.PRODUCT.length() % 10 +
                Build.TAGS.length() % 10 +
                Build.TYPE.length() % 10 +
                Build.USER.length() % 10; //13 digits
        params.put("udid", m_szDevIDShort);
        network_type = !NetUtil.isWifi(APP.getInstance().getApplicationContext()) ? 1 : 2;
        params.put("networkType", network_type + "");
        params.put("screenHeight", Global.screen_h + "");
        params.put("screenWidth", Global.screen_w + "");
        //v4.1把友盟的token作为公共参数传递
        params.put("pushToken", APP.getInstance().getPushAgent().getRegistrationId().toString());//友盟的token,
        // 只在登录，退出，开屏时传
        return checkParams(params);
    }


    //v4.2.2新加用来防止部分机型params为空时不请求数据的问题
    private Map<String, String> checkParams(Map<String, String> map) {
        Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> pairs = (Map.Entry<String, String>) it.next();
            if (pairs.getValue() == null) {
                map.put(pairs.getKey(), "");
            }
        }
        if (params != null) {
            map.putAll(params);
        }
        return map;
    }

    @Override
    protected void deliverResponse(T response) {
        if (listener != null) {
            listener.onResponse(response);
        }
    }

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {
        try {
            String ret = new String(response.data, HttpHeaderParser
                    .parseCharset(response.headers));
            for (int i = 0; i < ret.length(); i += 256) {
                int start = i;
                int end = ret.length() - 2 < i + 256 ? ret.length() - 1 : i + 256;
            }
            LogUtil.e("params", "result" + ret.toString());


            BaseResponse b = gson.fromJson(ret, BaseResponse.class);
            if (!b.isSuccess()) {
                Log.e("getVerifyCode", "ErrorResponseException");
                ErrorResponseException errorResponseException = new ErrorResponseException();
                errorResponseException.success = b.success;
                errorResponseException.data = ret;
                return Response.error(new VolleyError(b.getMsg(),
                        errorResponseException));
            }
            T fromJson = gson.fromJson(ret, clazz);
            return Response
                    .success(fromJson, HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            return Response.error(new ParseError(e));
        }
    }

    private int network_type;

    public static Map<String, String> getCommonMap() {
        long t = (int) (System.currentTimeMillis() / 1000);
        String time = Long.toString(t);//时间戳（单位秒）
        String nonce = "secretMirror_az_app";//任意字段
        String privateKey = "secretMirror_api";
        String temp = time + privateKey + nonce;
        String signature = SHA1.getSha1(temp);//sh1加密后的签名
        //        String token= Settings.getToken();//token
        Map<String, String> params = new LinkedHashMap<>();
        params.put("TIMESTAMP", time);
        params.put("NONCE", nonce);
        params.put("SIGNATURE", signature);
        params.put("os", "Android" + Build.VERSION.RELEASE);
        params.put("appVersion", Constants.version_name);
        params.put("platform", "Android");
        params.put("phoneModel", Build.MODEL);

        //这个只能通过wifi网段区分唯一，不准确
        //        WifiManager wm = (WifiManager) APP.getInstance().getSystemService(Context.WIFI_SERVICE);
        //        String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
        //        params.put("udid", m_szWLANMAC);

        //这个在安卓6.0的时候有问题
        //        final TelephonyManager tm = (TelephonyManager) APP.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
        //        final String tmDevice = "" + tm.getDeviceId();
        //        params.put("udid", tmDevice);

        /*
        * 不愿加入READ_PHONE_STATE许可。而你仍然想获得唯一序列号之类的东西。这时你可以通过取出ROM版本、制造商、CPU型号、
        * 以及其他硬件信息来实现这一点。这样计算出来的ID不是唯一的（因为如果两个手机应用了同样的硬件以及Rom 镜像）。
        * 但应当明白的是，出现类似情况的可能性基本可以忽略。要实现这一点，你可以使用Build类:*/
        String m_szDevIDShort = "35" +
                Build.BOARD.length() % 10 +
                Build.BRAND.length() % 10 +
                Build.CPU_ABI.length() % 10 +
                Build.DEVICE.length() % 10 +
                Build.DISPLAY.length() % 10 +
                Build.HOST.length() % 10 +
                Build.ID.length() % 10 +
                Build.MANUFACTURER.length() % 10 +
                Build.MODEL.length() % 10 +
                Build.PRODUCT.length() % 10 +
                Build.TAGS.length() % 10 +
                Build.TYPE.length() % 10 +
                Build.USER.length() % 10; //13 digits
        params.put("udid", m_szDevIDShort);
        int network_type = !NetUtil.isWifi(APP.getInstance().getApplicationContext()) ? 1 : 2;
        params.put("networkType", network_type + "");
        params.put("screenHeight", Global.screen_h + "");
        params.put("screenWidth", Global.screen_w + "");
        //v4.1把友盟的token作为公共参数传递
        params.put("pushToken", APP.getInstance().getPushAgent().getRegistrationId().toString());//友盟的token,
        if (null != Global.user && !TextUtils.isEmpty(Global.user.getUid()))
            params.put("uid", Global.user.getUid());
        // 只在登录，退出，开屏时传
        return params;
    }


    //    @Override
    //    public Map<String, String> getHeaders() throws AuthFailureError {
    //        Map<String, String> params = new HashMap<>();
    //        params.put("Content-Type", "application/x-www-form-urlencoded");
    //        return params;
    //    }
}
